#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
using namespace std;
const int N = 100010;
double dp[N][2];
// a数组存放的是竹子的下标
int a[N];
const double up = 0.7, down = 1.3;
typedef pair<int, int> PII;
PII flash[N];
int n;

double go_time(int st, int ed)
{
    if(st > ed) return ((double)st - ed) / down;
    else return ((double)ed - st) / up;
}
// 思路：状态机动态规划
// 初始化小数最大值可以用127！！！

int main()
{
    cin >> n;
    memset(dp, 127, sizeof dp);
    dp[0][0] = 0;
    // flash[i].first ： 前一个竹子起点
    // flash[i].second: 当前竹子终点
    flash[1].first = flash[1].second = 0;
    for(int i = 1; i <= n; ++i) cin >> a[i];
    for(int i = 2; i <= n; ++i) cin >> flash[i].first >> flash[i].second;
    for(int i = 1; i <= n; ++i)
    {
        // 如果不是第一根竹子，那就有用传送门的可能
        // 用传送门又有两种情况 ：从上一次传送门走到当前传送门（上一次也是传送）
        //（上一次不是传送）：从地面走到传送门
        if(i != 1)
        {
            // 上一次是走到第i - 1根杆子
            // if(i == 2) printf("%d %.2lf\n", flash[1].f)
            double tmp1 = dp[i - 1][0] + go_time(0, flash[i].first);
            // 上一次是传送到第i - 1根杆子
            double tmp2 = dp[i - 1][1] + go_time(flash[i - 1].second, flash[i].first);
            dp[i][1] = min(tmp1, tmp2);
        }
        // 走到第i跟竹子
        // 如果上一次也是用走的
        double tmp1 = dp[i - 1][0] + a[i] - a[i - 1];
        // 如果上一次是用传送的
        double tmp2 = dp[i - 1][1] + a[i] - a[i - 1] + go_time(flash[i - 1].second, 0);
        dp[i][0] = min(tmp1, tmp2);
    }
    // for(int i = 1; i <= n; ++i) printf("%.2lf %.2lf\n", dp[i][0], dp[i][1]);
    printf("%.2lf\n", min(dp[n][0], dp[n][1] + go_time(flash[n].second, 0)));
    // cout << min(dp[n][0], dp[n][1] + go_time(flash[n].second, 0)) << endl;
    return 0;
}